From cd9a15f42ef35449a8ad480352f9f5495eb37c30 Mon Sep 17 00:00:00 2001
From: Boris Kolpackov <boris@codesynthesis.com>
Date: Fri, 15 Mar 2019 17:37:28 +0200
Subject: [PATCH] Add initial support for GCC 9

[Upstream: 841140bbf13ae2bfaa5978a181718cda0a8edae7]
Signed-off-by: Kamel Bouhara <kamel.bouhara@bootlin.com>
---
 odb/cxx-lexer.cxx | 33 +++++++++++++++++++++++++++------
 odb/gcc.hxx       | 32 ++++++++++++++++++++++++++++++++
 odb/include.cxx   |  3 +++
 odb/plugin.cxx    | 45 ++++++++++++++++++++++++++++++---------------
 4 files changed, 92 insertions(+), 21 deletions(-)

diff --git a/odb/cxx-lexer.cxx b/odb/cxx-lexer.cxx
index cfebbb5..acd13be 100644
--- a/odb/cxx-lexer.cxx
+++ b/odb/cxx-lexer.cxx
@@ -143,12 +143,20 @@ translate ()
 // Diagnostics callback.
 //
 extern "C" bool
-cpp_error_callback (
+cpp_diagnostic_callback (
   cpp_reader* reader,
+#if BUILDING_GCC_MAJOR >= 9
+  cpp_diagnostic_level level,
+#else
   int level,
+#endif
 #if BUILDING_GCC_MAJOR > 4 || BUILDING_GCC_MAJOR == 4 && BUILDING_GCC_MINOR > 5
+#if BUILDING_GCC_MAJOR >= 9
+  cpp_warning_reason,
+#else
   int /*reason*/, // Added in GCC 4.6.0.
 #endif
+#endif
 #if BUILDING_GCC_MAJOR <= 5
   location_t,
   unsigned int,
@@ -185,10 +193,14 @@ cpp_error_callback (
     vfprintf (stderr, msg, *ap);
     fprintf (stderr, "\n");
 
-    // By resetting the error callback we indicate to cxx_string_lexer
-    // that there was an error.
+    // By resetting the callback we indicate to cxx_string_lexer that there
+    // was an error.
     //
+#if BUILDING_GCC_MAJOR >= 9
+    cpp_get_callbacks (reader)->diagnostic = 0;
+#else
     cpp_get_callbacks (reader)->error = 0;
+#endif
     return true;
   }
 
@@ -247,7 +259,12 @@ start (string const& data)
   // The previous lexing session should have popped the buffer.
   //
   assert (cpp_get_buffer (reader_) == 0);
-  callbacks_->error = &cpp_error_callback;
+
+#if BUILDING_GCC_MAJOR >= 9
+  callbacks_->diagnostic = &cpp_diagnostic_callback;
+#else
+  callbacks_->error = &cpp_diagnostic_callback;
+#endif
 
   data_ = data;
   buf_ = data;
@@ -267,10 +284,14 @@ next (string& token, tree* node)
   token.clear ();
   cpp_token const* t (cpp_get_token (reader_));
 
-  // If there was an error, the error callback will be reset to 0.
-  // Diagnostics has already been issued.
+  // If there was an error, the callback will be reset to 0. Diagnostics has
+  // already been issued.
   //
+#if BUILDING_GCC_MAJOR >= 9
+  if (callbacks_->diagnostic == 0)
+#else
   if (callbacks_->error == 0)
+#endif
     throw invalid_input ();
 
   cpp_ttype tt (t->type);
diff --git a/odb/gcc.hxx b/odb/gcc.hxx
index a22357d..0304192 100644
--- a/odb/gcc.hxx
+++ b/odb/gcc.hxx
@@ -158,4 +158,36 @@ gcc_tree_code_name (gcc_tree_code_type tc) {return tree_code_name[tc];}
 #  define anon_aggrname_p(X) ANON_AGGRNAME_P(X)
 #endif
 
+// In GCC 9:
+//
+// INCLUDED_FROM     Became linemap_included_from_linemap().
+// LAST_SOURCE_LINE  Was removed apparently as no longer used. Studying
+//                   the line-map.h diff from 8.3 suggests that the old
+//                   implementation should still work.
+//
+#if BUILDING_GCC_MAJOR >= 9
+
+inline const line_map_ordinary*
+INCLUDED_FROM (line_maps* set, const line_map_ordinary* map)
+{
+  return linemap_included_from_linemap (set, map);
+}
+
+inline source_location
+LAST_SOURCE_LINE_LOCATION (const line_map_ordinary* map)
+{
+  return (((map[1].start_location - 1
+	    - map->start_location)
+	   & ~((1 << map->m_column_and_range_bits) - 1))
+	  + map->start_location);
+}
+
+inline linenum_type
+LAST_SOURCE_LINE (const line_map_ordinary* map)
+{
+  return SOURCE_LINE (map, LAST_SOURCE_LINE_LOCATION (map));
+}
+
+#endif
+
 #endif // ODB_GCC_HXX
diff --git a/odb/include.cxx b/odb/include.cxx
index 08c93ce..0082f5e 100644
--- a/odb/include.cxx
+++ b/odb/include.cxx
@@ -584,6 +584,9 @@ namespace
 
     for (include_map::iterator i (imap.begin ()), e (imap.end ()); i != e; ++i)
     {
+      // Note that the LAST_SOURCE_LINE value of a map that includes another
+      // map is the line of that include.
+
       /*
       cerr << endl
            << i->first << " included from" << endl;
diff --git a/odb/plugin.cxx b/odb/plugin.cxx
index 0fac632..892f27c 100644
--- a/odb/plugin.cxx
+++ b/odb/plugin.cxx
@@ -44,10 +44,15 @@ paths profile_paths_;
 path file_;    // File being compiled.
 paths inputs_; // List of input files in at-once mode or just file_.
 
-bool (*cpp_error_prev) (
+bool (*cpp_diagnostic_prev) (
   cpp_reader*,
+#if BUILDING_GCC_MAJOR >= 9
+  cpp_diagnostic_level,
+  cpp_warning_reason,
+#else
   int,
   int,
+#endif
 #if BUILDING_GCC_MAJOR >= 6
   rich_location*,
 #else
@@ -58,17 +63,22 @@ bool (*cpp_error_prev) (
   va_list*);
 
 static bool
-cpp_error_filter (cpp_reader* r,
-                  int level,
-                  int reason,
+cpp_diagnostic_filter (cpp_reader* r,
+#if BUILDING_GCC_MAJOR >= 9
+                       cpp_diagnostic_level level,
+                       cpp_warning_reason reason,
+#else
+                       int level,
+                       int reason,
+#endif
 #if BUILDING_GCC_MAJOR >= 6
-                  rich_location* l,
+                       rich_location* l,
 #else
-                  location_t l,
-                  unsigned int column_override,
+                       location_t l,
+                       unsigned int column_override,
 #endif
-                  const char* msg,
-                  va_list* ap)
+                       const char* msg,
+                       va_list* ap)
 {
   // #pragma once in the main file. Note that the message that we get is
   // potentially translated so we search for the substring (there is
@@ -80,7 +90,7 @@ cpp_error_filter (cpp_reader* r,
   if (strstr (msg, "#pragma once") != 0)
     return true;
 
-  return cpp_error_prev (
+  return cpp_diagnostic_prev (
     r,
     level,
     reason,
@@ -119,15 +129,20 @@ start_unit_callback (void*, void*)
   //
   cpp_callbacks* cb (cpp_get_callbacks (parse_in));
 
-  if (cb->error == 0)
+#if BUILDING_GCC_MAJOR >= 9
+  cpp_diagnostic_prev = cb->diagnostic;
+  cb->diagnostic = &cpp_diagnostic_filter;
+#else
+  cpp_diagnostic_prev = cb->error;
+  cb->error = &cpp_diagnostic_filter;
+#endif
+
+  if (cpp_diagnostic_prev == 0)
   {
-    cerr << "ice: expected cpp error callback to be set" << endl;
+    cerr << "ice: expected cpp diagnostic callback to be set" << endl;
     exit (1);
   }
 
-  cpp_error_prev = cb->error;
-  cb->error = &cpp_error_filter;
-
   // Set the directory of the main file (stdin) to that of the orginal
   // file so that relative inclusion works. Also adjust the path and
   // re-stat the file so that #pragma once works.
-- 
2.25.0

